﻿using System;
using System.Collections.Generic;


namespace advadev.CanOpen
{

    /// <summary>
    /// Must be implemented from each can open value object
    /// </summary>
    public interface ICanOpenValueObject : ICanOpenObject
    {

        /// <summary>
        /// When implemented, occures when the value is changing
        /// </summary>
        event ValueChangingEventHandler ValueChanging;

        /// <summary>
        /// When implemented, occures when the value is changed
        /// </summary>
        event ValueChangedEventHandler ValueChanged;

        /// <summary>
        /// When implemented, gets the index of the object
        /// </summary>
        UInt16 Index
        {
            get;
        }

        /// <summary>
        /// When implemented, gets the sub index of the object
        /// </summary>
        byte SubIndex
        {
            get;
        }

        /// <summary>
        /// When implemented, gets a flag indicating whether the object is
        /// readable
        /// </summary>
        bool IsReadable
        {
            get;
        }

        /// <summary>
        /// When implemented, gets a flag indicating whether the object is
        /// writeable
        /// </summary>
        bool IsWriteable
        {
            get;
        }

        /// <summary>
        /// When implemented, gets a flag indicating whether a expedited
        /// download transfer is possible for this object
        /// </summary>
        bool IsExpeditedDownloadTransferPossible
        {
            get;
        }

        /// <summary>
        /// When implemented, gets a flag indicating whether a expedited upload
        /// transfer is possible for this object
        /// </summary>
        bool IsExpeditedUploadTransferPossible
        {
            get;
        }

        /// <summary>
        /// When implemented, gets a flag indicating whether a block download
        /// transfer is advised for this object
        /// </summary>
        bool IsBlockDownloadTransferAdvised
        {
            get;
        }

        /// <summary>
        /// When implemented, gets a flag indicating whether a block upload
        /// transfer is advised for this object
        /// </summary>
        bool IsBlockUploadTransferAdvised
        {
            get;
        }

        /// <summary>
        /// When implemented, gets or sets a flag indicating whether the value
        /// changed event raising is paused
        /// </summary>
        bool IsValueChangedEventRaisingPaused
        {
            get;
            set;
        }

        /// <summary>
        /// When implemented, gets or sets the byte order
        /// </summary>
        CanOpenByteOrder ByteOrder
        {
            get;
            set;
        }

        /// <summary>
        /// When implemented, gets the last service data object upload sequence
        /// </summary>
        IList<CanOpenMessage> LastServiceDataObjectUploadSequence
        {
            get;
        }

        /// <summary>
        /// When implemented, gets the last service data object download
        /// sequence
        /// </summary>
        IList<CanOpenMessage> LastServiceDataObjectDownloadSequence
        {
            get;
        }

        /// <summary>
        /// When implemented, converts the value of the object to a byte array
        /// </summary>
        /// <returns>
        /// Value of the object converted to a byte array
        /// </returns>
        IList<byte> ToByteArray();

        /// <summary>
        /// When implemented, converts the given byte array and sets the result
        /// as value
        /// </summary>
        /// <param name="byteArray">
        /// Byte array to convert and set as value
        /// </param>
        void FromByteArray(IList<byte> byteArray);

        /// <summary>
        /// When implemented, converts the given byte array and sets the result
        /// as value after validating the value
        /// </summary>
        /// <param name="byteArray">
        /// Byte array to convert and set as value
        /// </param>
        /// <param name="abortCode">
        /// Abort code if the validation failed (otherwise null)
        /// </param>
        /// <returns>
        /// True, if the new value is valid, false otherwise
        /// </returns>
        bool FromByteArray(IList<byte> byteArray, out CanOpenAbortCode abortCode);

    }

}
